package org.goldenport.g3.messages.entity

import java.io._
import org.goldenport.util.{QSymbol, QSymbolSet}
import org.goldenport.g3.G3Command
import org.goldenport.g3.messages._
import org.goldenport.g3.messages.query._

/**
 * @since   Aug. 20, 2010
 * @version Sep. 18, 2010
 * @author  ASAMI, Tomoharu
 */

abstract class EntityCommand(uris: QSymbolSet) extends G3Command(uris.names) {
  def this(uri: QSymbol) = this(QSymbolSet(uri))
}

/**
 * Creates a entity class.
 */
class CreateEntityClass(uri: QSymbol) extends EntityCommand(uri) {
}

object Create {
  def apply(uri: QSymbol) = new CreateEntityClass(uri)
}

/**
 * Fetch or Query entity instances by ids or condition.
 */
class FetchEntity(uri: QSymbol, val ids: List[AnyRef]) extends EntityCommand(uri) {
}

class QueryEntity(val query: RecordQuery) extends EntityCommand(query.uris) {
}

class QueryEntityExpression(uri: QSymbol, val expression: Expression) extends EntityCommand(uri) {
}

object Fetch {
  def apply(uri: QSymbol, id: Any) = new FetchEntity(uri, List(id.asInstanceOf[AnyRef]))

  def apply(uri: QSymbol, ids: List[AnyRef]) = new FetchEntity(uri, ids)
}

object Query {
  def apply(query: RecordQuery) = new QueryEntity(query)

  def apply(uri: QSymbol, expression: Expression) = new QueryEntityExpression(uri, expression)
}

/**
 * Inserts entity instances.
 */
class InsertEntity(uri: QSymbol, val record: Record) extends EntityCommand(uri) {
}

class InsertEntitySet(uri: QSymbol, val records: RecordSet) extends EntityCommand(uri) {
}

object Insert {
  def apply(uri: QSymbol, record: Record) = new InsertEntity(uri, record)

  def apply(uri: QSymbol, records: RecordSet) = new InsertEntitySet(uri, records)

  def apply(uri: QSymbol, records: List[Record]) = new InsertEntitySet(uri, RecordSet(records))
}

/**
 * Updates entity instances.
 */
class UpdateEntity(uri: QSymbol, val record: Record) extends EntityCommand(uri) {
}

class UpdateEntitySet(uri: QSymbol, val records: RecordSet) extends EntityCommand(uri) {
}

object Update {
  def apply(uri: QSymbol, record: Record) = new UpdateEntity(uri, record)

  def apply(uri: QSymbol, records: RecordSet) = new UpdateEntitySet(uri, records)

  def apply(uri: QSymbol, records: List[Record]) = new UpdateEntitySet(uri, RecordSet(records))
}

/**
 * Deletes entity instances by ids , example, or expression.
 */
class DeleteEntityId(uri: QSymbol, val ids: List[AnyRef]) extends EntityCommand(uri) {
}

class DeleteEntityExample(uri: QSymbol, val record: Record) extends EntityCommand(uri) {
}

class DeleteEntityExpression(uri: QSymbol, val expression: Expression) extends EntityCommand(uri) {
}

object Delete {
  def apply(uri: QSymbol, id: AnyRef) = new DeleteEntityId(uri, List(id))

  def apply(uri: QSymbol, ids: List[AnyRef]) = new DeleteEntityId(uri, ids)

  def apply(uri: QSymbol, record: Record) = new DeleteEntityExample(uri, record)

  def apply(uri: QSymbol, expression: Expression) = new DeleteEntityExpression(uri, expression)
}

/**
 * Drops a kind.
 */
class DropEntityClass(uri: QSymbol) extends EntityCommand(uri) {
}

object Drop {
  def apply(uri: QSymbol) = new DropEntityClass(uri)
}
